package com.cykj.pos.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cykj.common.annotation.DataSource;
import com.cykj.common.enums.DataSourceType;
import com.cykj.pos.domain.BizCrownSpecial;
import com.cykj.pos.domain.BizMerchBill;
import com.cykj.pos.domain.BizShareDetail;
import com.cykj.pos.domain.dto.ShareCalcDetailDTO;
import com.cykj.pos.mapper.BizShareDetailMapper;
import com.cykj.pos.profit.dto.ShareDetailDTO;
import com.cykj.pos.service.IBizShareDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 分润明细Service业务层处理
 */
@Service
public class BizShareDetailServiceImpl extends ServiceImpl<BizShareDetailMapper, BizShareDetail> implements IBizShareDetailService {

    @Resource
    private BizShareDetailMapper bizShareDetailMapper;

    @Override
    @DataSource(DataSourceType.SLAVE)
    public BizShareDetail queryOwnDealInfo(ShareDetailDTO shareDetailDTO) {
        BizShareDetail bizShareDetail = bizShareDetailMapper.queryOwnDealInfo(shareDetailDTO);
        return bizShareDetail;
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public BizShareDetail queryParentDealInfo(ShareDetailDTO shareDetailDTO) {
        BizShareDetail bizShareDetail = bizShareDetailMapper.queryParentDealInfo(shareDetailDTO);
        return bizShareDetail;
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public List<ShareDetailDTO> queryParentMerchId(ShareDetailDTO shareDetailDTO) {
        List<ShareDetailDTO> list = bizShareDetailMapper.queryParentMerchId(shareDetailDTO);
        return list;
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public BizShareDetail queryParentDealSum(ShareDetailDTO shareDetailDTO) {
        BizShareDetail bizShareDetail = bizShareDetailMapper.queryParentDealSum(shareDetailDTO);
        return bizShareDetail;
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public BigDecimal queryTransAmount(ShareDetailDTO shareDetailDTO) {
        BigDecimal bigDecimal = bizShareDetailMapper.queryTransAmount(shareDetailDTO);
        return bigDecimal;
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public BigDecimal queryParentAllDealSum(ShareDetailDTO shareDetailDTO) {
        BigDecimal bigDecimal = bizShareDetailMapper.queryParentAllDealSum(shareDetailDTO);
        return bigDecimal;
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public List<ShareDetailDTO> queryMerchantInfo() {
        List<ShareDetailDTO> list = bizShareDetailMapper.queryMerchantInfo();
        return list;
    }

    @Override
    public void saveShareDetail(BizShareDetail bizShareDetail) {
        int row = bizShareDetailMapper.insert(bizShareDetail);
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public ShareDetailDTO queryParentName(Long parentId) {
        ShareDetailDTO shareDetailDTO1 = bizShareDetailMapper.queryParentName(parentId);
        return shareDetailDTO1;
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public List<BizShareDetail> queryAllShareByOrderId(String orderId) {
        LambdaQueryWrapper<BizShareDetail> wrapper = Wrappers.lambdaQuery();
        wrapper.eq(BizShareDetail::getOrderId,orderId);
        List<BizShareDetail> list = this.list(wrapper);
        return list;
    }

    @Override
    public String updateCheckStatus(BizShareDetail bizShareDetail) {
        LambdaUpdateWrapper<BizShareDetail> wrapper = Wrappers.lambdaUpdate();
        wrapper.eq(BizShareDetail::getMerchId,bizShareDetail.getMerchId());
        // 更改分润账单状态
        bizShareDetail.setCheckStatus(3L);
        int row = bizShareDetailMapper.update(bizShareDetail,wrapper);
        if (row==0)
            return "LOSE";
        return "SUCCESS";
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public BizShareDetail queryParentDealSlotCard(ShareDetailDTO shareDetailDTO) {
        BizShareDetail bizShareDetail = bizShareDetailMapper.queryParentDealSlotCard(shareDetailDTO);
        return bizShareDetail;
    }

    @Override
    @DataSource(DataSourceType.SLAVE)
    public BizShareDetail queryBillTypeTwo(BizMerchBill bizMerchBill) {
        BizShareDetail bizShareDetail = bizShareDetailMapper.queryBillTypeTwo(bizMerchBill);
        return bizShareDetail;
    }

    @Override
    public List<BizCrownSpecial> querySpecialCrown() {
        return bizShareDetailMapper.querySpecialCrown();
    }

    @Override
    public void updateCrownSpecial(BizCrownSpecial bizCrownSpecial) {
        bizShareDetailMapper.updateCrownSpecial(bizCrownSpecial);
    }
    // 生成数结构
    public List<LinkedList<ShareCalcDetailDTO>> makeTree(ShareCalcDetailDTO root,Map<Long,ShareCalcDetailDTO> children,List<ShareCalcDetailDTO> leafChildren){
        List<LinkedList<ShareCalcDetailDTO>> leafList = new ArrayList<>();
        // 遍历
        for(ShareCalcDetailDTO leaf:leafChildren){
            //  每一个都是一个链表
            LinkedList<ShareCalcDetailDTO> memberLinkedList = new LinkedList<>();
            memberLinkedList.addFirst(leaf);
            // 获得父亲id
            while(true){
                Long leafId = leaf.getParentId();
                if(leafId==root.getMerchId()){ //就是根的直接子类
                    // 加根
                    memberLinkedList.addFirst(root);
                    break;
                }
                // 获得父对象
                ShareCalcDetailDTO leafParentMember = children.get(leafId);
                if(leafParentMember!=null){
                    memberLinkedList.addFirst(leafParentMember);
                }
                // 判断是否是根节点
                if(leafParentMember==null){ //根节点
                    // 加根
                    memberLinkedList.addFirst(root);
                    break;
                }
                leaf = leafParentMember; // 叶子节点就变为父节点
            }
            leafList.add(memberLinkedList);
        }
        return leafList;
    }
    // 把List转换成Map
    public Map<Long,ShareCalcDetailDTO> listSwitchMap(List<ShareCalcDetailDTO> childList){
        Map<Long,ShareCalcDetailDTO> map = new Hashtable<>();
        for(ShareCalcDetailDTO child:childList){
            map.put(child.getMerchId(),child);
        }
        return map;
    }
    // 计算分润
    public BigDecimal calcShareResult(ShareCalcDetailDTO root){
        // 销售额为0  没有提成
        if(root.getSaleMoney().compareTo(BigDecimal.ZERO)==0){
            return BigDecimal.ZERO;
        }
        // 获得根节点对象
        // Member root = shareDetailDao.selectShareDetailByMerchId(merchId);
        // 把所有的子节点放到一个Map中
        List<ShareCalcDetailDTO> childList = bizShareDetailMapper.selectShareDetailListByMerchIdAndOrderId(root); // 50L
        // 把集合转换成Map
        Map<Long,ShareCalcDetailDTO> children = listSwitchMap(childList); //
        // 获得所有的叶子节点
        List<ShareCalcDetailDTO> leafChildren = bizShareDetailMapper.selectShareDetailLeafListByMerchIdAndOrderId(root);
        // 开始进行分支组件
        List<LinkedList<ShareCalcDetailDTO>> linkedLists = makeTree(root,children,leafChildren);
        // 开辟一个新集合  存新生成的根直接子节点
        List<LinkedList<ShareCalcDetailDTO>> newLinkedLists = new ArrayList<>();
        // 开辟一个Map存储特殊群体升级为第一级孩子的集合
        Hashtable<Long,ShareCalcDetailDTO> newFirstChildren = new Hashtable<>();
        // 剔除的节点集合
        Hashtable<Long,ShareCalcDetailDTO> deleteChildren = new Hashtable<>();

        System.out.println(linkedLists);
        // 计算提成
        // 计算是否存在特殊人群
        for(LinkedList<ShareCalcDetailDTO> leafLinkedList:linkedLists){
            ShareCalcDetailDTO firstChildRoot = leafLinkedList.get(1);
            // 剔除的第一级根节点 是否大于根节点
            if(!deleteChildren.containsKey(firstChildRoot.getMerchId())){
                // 判断第一层是否大于根节点
                if(firstChildRoot.getSalePercent().compareTo(root.getSalePercent())>=0){ // 大于等于
                    // 从根中刨除该提成  总体提成减去个人提成
                    root.setSaleMoney(root.getSaleMoney().subtract(firstChildRoot.getSaleMoney()));
                    // 自己的提成变为0
                    firstChildRoot.setSaleMoney(new BigDecimal("0.00"));
                    deleteChildren.put(firstChildRoot.getMerchId(),firstChildRoot);
                }else{
                    // 直接子节点小于父节点分润比例
                    // 判断其他子节点是否大于该提成分润
                    ArrayList<Integer> maxMemberIndexList = new ArrayList<>();
                    for(int i=2;i<leafLinkedList.size();i++){
                        ShareCalcDetailDTO m = leafLinkedList.get(i);
                        if(m.getSalePercent().compareTo(firstChildRoot.getSalePercent())>0){
                            maxMemberIndexList.add(i);
                        }
                    }
                    if(maxMemberIndexList.size()>0){
                        // 存在比上1级节点大的子节点
                        // 从最下层大于根的直接子节点的节点开始查看  如果该值小于上层某个节点 那么该节点就无需处理
                        for(int i2=maxMemberIndexList.size()-1;i2>=0;i2--){
                            Integer index = maxMemberIndexList.get(i2);
                            ShareCalcDetailDTO m = leafLinkedList.get(index);
                            // 判断是否已经提升为根的直接子节点或者已经被移除了
                            if(newFirstChildren.containsKey(m.getMerchId()) || deleteChildren.containsKey(m.getMerchId())){
                                continue;
                            }
                            // 判断是否需要减去
                            boolean flag1 = false;
                            for(int j=i2-1;j>=0;j--){
                                Integer index2 = maxMemberIndexList.get(j);
                                ShareCalcDetailDTO m2 = leafLinkedList.get(index2);
                                if(m2.getSalePercent().compareTo(m.getSalePercent())>=0){
                                    // 比他的提层高  那么就舍去  就可以
                                    flag1=true;
                                    break;
                                }
                            }
                            if(flag1){
                                continue;
                            }
                            // 开始遍历他所有的上级父目录  看是否大于上一级  大就减去销售额
                            for(int i=index-1;i>0;i--){ // 从上一级 到根节点的第一层子根
                                ShareCalcDetailDTO p = leafLinkedList.get(i);
                                // 都需要减去大于第1层的销售额
                                p.setSaleMoney(p.getSaleMoney().subtract(m.getSaleMoney()));
                            }
                            // 再和父亲进行比较  如果大于父亲的直接删除
                            if(m.getSalePercent().compareTo(root.getSalePercent())>=0){ // 大于等于
                                // 剔除前  需要验证父级是否已经被剔除了  如果已经剔除  就不需要剔除了
                                // 遍历该节点的所有父亲
                                ShareCalcDetailDTO parent = children.get(m.getParentId());
                                boolean flag2 = false;
                                while(true){
                                    if(parent==null){
                                        break;
                                    }
                                    if(deleteChildren.containsKey(parent.getMerchId())){
                                        flag2=true;
                                        break;
                                    }
                                    parent = children.get(parent.getParentId());
                                }
                                if(!flag2){
                                    // 从根中刨除该提成  总体提成减去个人提成
                                    root.setSaleMoney(root.getSaleMoney().subtract(m.getSaleMoney()));
                                    // 自己的提成变为0
                                    m.setSaleMoney(new BigDecimal("0.00"));
                                    deleteChildren.put(m.getMerchId(),m); // 存起来
                                }
                            }else{
                                if(!newFirstChildren.containsKey(m.getMerchId())){
                                    // 如果小于就作为父亲的第一个子节点计算提成
                                    LinkedList<ShareCalcDetailDTO> newLinkedList = new LinkedList<>();
                                    newLinkedList.add(root);
                                    newLinkedList.add(m);
                                    // 加入到新节点链表集合中
                                    newLinkedLists.add(newLinkedList);
                                    // 把新生成的直接节点  添加一个Map中
                                    newFirstChildren.put(m.getMerchId(),m);
                                }
                            }
                        }
                    }
                }
            }
            // 计算的过程中   只要遇到父对象得总销售额是0  就直接返回了
            if(root.getSaleMoney().compareTo(BigDecimal.ZERO)==0){
                return BigDecimal.ZERO;
            }
        }
        // 钱汇总
        BigDecimal totalMoney = root.getSaleMoney().multiply(root.getSalePercent()).setScale(4,BigDecimal.ROUND_DOWN); // 小数点保留2位  四射侮辱
        Hashtable<Long,ShareCalcDetailDTO> firstChildList = new Hashtable<>();
        for(LinkedList<ShareCalcDetailDTO> leafLinkedList:linkedLists){
            ShareCalcDetailDTO firstChildRoot = leafLinkedList.get(1);
            if(firstChildList.containsKey(firstChildRoot.getMerchId()))
                continue;
            firstChildList.put(firstChildRoot.getMerchId(),firstChildRoot);
            BigDecimal money =  firstChildRoot.getSaleMoney().multiply(firstChildRoot.getSalePercent()).setScale(4,BigDecimal.ROUND_DOWN);
            totalMoney=totalMoney.subtract(money);
        }

        // 算新生成的链表信息
        for(LinkedList<ShareCalcDetailDTO> leafLinkedList:newLinkedLists){
            ShareCalcDetailDTO firstChildRoot = leafLinkedList.get(1);
            if(firstChildList.containsKey(firstChildRoot.getMerchId()))
                continue;
            firstChildList.put(firstChildRoot.getMerchId(),firstChildRoot);
            BigDecimal money =  firstChildRoot.getSaleMoney().multiply(firstChildRoot.getSalePercent()).setScale(4,BigDecimal.ROUND_DOWN);
            totalMoney=totalMoney.subtract(money);
        }
        System.out.println(root.getMerchId()+"的名称是：" +root.getMerchName()+",提成是："+totalMoney);
        return totalMoney;
    }

    @Override
    @Transactional
    public boolean calcFinalShare(String orderId) {
        // 更新一下特殊分润的用户信息
        bizShareDetailMapper.updateSpecialShareDetail();
        // 获得所有商户信息
        List<ShareCalcDetailDTO> memberList = bizShareDetailMapper.selectShareDetailListByOrderId(orderId);
        for(ShareCalcDetailDTO member:memberList){
            BigDecimal finalDealProfit = calcShareResult(member);
            member.setFinalDealProfit(finalDealProfit);
        }
        // 更新数据库表
        int rows = 0;
        for(ShareCalcDetailDTO shareCalcDetailDTO:memberList){
            int row = bizShareDetailMapper.updateFinalDealProfitById(shareCalcDetailDTO);
            rows = rows+row;
        }
        return rows>0?true:false;
    }
}
